home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UMenuView.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  18.5 KB  |  783 lines  |  [TEXT/MPS ]

  1. /*
  2.   • List units defining any constants, types or classes that are required for your implementation
  3.   section (e.g. Packages or Errors)
  4.   • Also list units defining the classes that you declared EXTERNAL in the interface section
  5.   or wish to use in the implementation section.
  6.   • Also list the units required by the interfaces of the above units.
  7. */
  8.  
  9. #include "UMenuView.h"
  10.  
  11. #ifndef __UGEOMETRY__
  12. #include <UGeometry.h>
  13. #endif
  14.  
  15. #ifndef __ULIST__
  16. #include <UList.h>
  17. #endif
  18.  
  19. #ifndef __UEVENT__
  20. #include <UEvent.h>
  21. #endif
  22.  
  23. #ifndef __UCOMMAND__
  24. #include <UCommand.h>
  25. #endif
  26.  
  27. #ifndef __EDITIONS__
  28. #include <Editions.h>
  29. #endif
  30.  
  31. #ifndef __DIALOGS__
  32. #include <Dialogs.h>
  33. #endif
  34.  
  35. #ifndef __UAPPLICATION__
  36. #include <UApplication.h>
  37. #endif
  38.  
  39. #ifndef __UDOCUMENT__
  40. #include <UDocument.h>
  41. #endif
  42.  
  43. #ifndef __UFAILURE__
  44. #include <UFailure.h>
  45. #endif
  46.  
  47. #ifndef __UMACAPPUTILITIES__
  48. #include <UMacAppUtilities.h>
  49. #endif
  50.  
  51. #ifndef __UPATCH__
  52. #include <UPatch.h>
  53. #endif
  54.  
  55. #ifndef __UMACAPPGLOBALS__
  56. #include <UMacAppGlobals.h>
  57. #endif
  58.  
  59. #ifndef __UMENUMGR__
  60. #include <UMenuMgr.h>
  61. #endif
  62.  
  63. #ifndef __UMEMORY__
  64. #include <UMemory.h>
  65. #endif
  66.  
  67. #ifndef __ERRORS__
  68. #include <Errors.h>
  69. #endif
  70.  
  71. #ifndef __TOOLUTILS__
  72. #include <ToolUtils.h>
  73. #endif
  74.  
  75. #if qDebugMsg
  76. #ifndef __STDIO__
  77. #include <StdIO.h>
  78. #endif
  79. #endif
  80.  
  81. //--------------------------------------------------------------------------------------------------
  82. Boolean gTrackingInMenu = FALSE;
  83.  
  84. //--------------------------------------------------------------------------------------------------
  85. struct MenuRec
  86. {
  87.     short mID;
  88.     TMenuView* mObject;
  89. };
  90.  
  91.  
  92. typedef MenuRec MenuArray[4000];
  93. typedef MenuRec* MenuArrayPtr;
  94. typedef MenuRec** MenuArrayHandle;
  95.  
  96. //--------------------------------------------------------------------------------------------------
  97. CGrafPort pMenuCPort;                            /* Color port for compatibility. 
  98.                                                   Private grafPort used to focus the menu w/o
  99.                                                   messing up the Window Manager port. */
  100. MenuArrayHandle pMenuArray;                        // Used to map a MenuHandle to the TMenuView
  101. short pNumMenus;
  102. Handle pCustDefproc;                            // Replaces the menu's menuProc field 
  103.  
  104. //--------------------------------------------------------------------------------------------------
  105. // Returns the TickCount some time in the future. 
  106.  
  107. pascal long Future(long delta)
  108.  
  109. {
  110.     return TickCount() + delta;
  111. }
  112.  
  113. //--------------------------------------------------------------------------------------------------
  114.  
  115. #pragma segment MAMenuRes
  116.  
  117. pascal void WaitTickChange(void)
  118.  
  119. {
  120.     long now = TickCount();
  121.     while (TickCount() != now)
  122.         ;
  123. }
  124.  
  125. //--------------------------------------------------------------------------------------------------
  126.  
  127. #pragma segment MAMenuRes
  128.  
  129. pascal TMenuView* FindTMenuView(MenuHandle theMenu)
  130.  
  131. {
  132.     MenuArrayPtr p = *pMenuArray;
  133.     short id = (*theMenu)->menuID;
  134.  
  135.     for (short i = 0; i < pNumMenus; ++i)
  136.         if (p[i].mID == id)
  137.             return p[i].mObject;
  138.     return NULL;
  139. }
  140.  
  141. //--------------------------------------------------------------------------------------------------
  142. // Called by the MDEF resource. 
  143. /*$Push*/
  144. #if qTrace
  145. #pragma $D+
  146. #endif
  147.  
  148. #pragma segment MAMenuRes
  149.  
  150. pascal void MenuDefproc(short message,
  151.                         MenuHandle theMenu,
  152.                         Rect& menuRect,
  153.                         Point hitPt,
  154.                         short& whichItem)
  155.  
  156. {
  157.     long OldA5 = SetCurrentA5();                // ***** Called from trap patches *****
  158.     TMenuView * menuObj = FindTMenuView(theMenu);
  159. #if qDebug
  160.     if (menuObj == NULL)
  161.         ProgramBreak("MenuDefproc called with no TMenuView object");
  162. #endif
  163.  
  164.     // Dispatch to the TMenuView object 
  165.     menuObj->HandleDefproc(message, theMenu, menuRect, hitPt, whichItem);
  166.     SetA5(OldA5);
  167. }
  168. //$Pop
  169.  
  170. //--------------------------------------------------------------------------------------------------
  171. #pragma segment MAMenuInit
  172.  
  173. typedef struct JMP
  174. {
  175.     short opcode;
  176.     Ptr address;
  177. }    *JmpPtr, ** JmpHandle;
  178.  
  179. pascal void InitUMenuView(void)
  180.  
  181. {
  182.     JmpHandle h;
  183.  
  184.     if (qNeedsColorQD || gConfiguration.hasColorQD)
  185.         OpenCPort(&pMenuCPort);
  186.     else
  187.         OpenPort((GrafPtr) & pMenuCPort);
  188.     pNumMenus = 0;
  189.     pMenuArray = (MenuArrayHandle)NewPermHandle(0);
  190.  
  191.     h = (JmpHandle)NewHandle(6);
  192.     FailNIL(h);
  193.     (*h)->opcode = 0x4EF9;
  194.     (*h)->address = (Ptr) & MenuDefproc;
  195.     pCustDefproc = (Handle)h;
  196. }
  197.  
  198. //--------------------------------------------------------------------------------------------------
  199. #pragma segment MAMenuInit
  200. pascal void TMenuView::Initialize(void)            // override 
  201. {
  202.     inherited::Initialize();
  203.  
  204.     fBorder = gZeroRect;
  205.     fFlashInterval = -1;
  206.     fHighlighted = FALSE;
  207.     fMenuHandle = NULL;
  208.     fNextFlash = 0;
  209. }
  210.  
  211. //--------------------------------------------------------------------------------------------------
  212. #pragma segment MAMenuInit
  213.  
  214. pascal void TMenuView::IMenuView(short rsrcID,
  215.                                  short menuWidth,
  216.                                  short menuHeight)
  217.  
  218. {
  219.     MenuHandle m;
  220.     Rect r;
  221.     short item;
  222.     VPoint vp(menuHeight, menuWidth);
  223.  
  224.     // Initialize fields 
  225.     this->IView(NULL, NULL, gZeroVPt, vp, sizeVariable, sizeVariable);
  226.     fNextHandler = gApplication;                // so postcommand flows to the app 
  227.  
  228.     /*fFlashInterval = - 1;
  229.       fNextFlash = 0;*/
  230.  
  231.     if (rsrcID == 0)
  232.         fMenuHandle = NULL;
  233.     else
  234.     {
  235.         // Read in menu and set its defproc 
  236.         m = MAGetMenu(rsrcID);
  237.  
  238.         if (m == NULL)
  239.         {
  240. #if qDebugMsg
  241.             fprintf(stderr, "rsrcID = %4s", (char *) &rsrcID);
  242.             ProgramBreak("No such MENU!");
  243. #endif
  244.  
  245.             this->Free();
  246.             Failure(resNotFound, 0);
  247.         }
  248.  
  249.         ++pNumMenus;
  250.         SetHandleSize((Handle)pMenuArray, sizeof(MenuRec) * pNumMenus);
  251.         (*pMenuArray)[pNumMenus-1].mID = (*m)->menuID;
  252.         (*pMenuArray)[pNumMenus-1].mObject = this;
  253.  
  254.         (*m)->menuProc = pCustDefproc;
  255.         fMenuHandle = m;
  256.  
  257.         r = gZeroRect;
  258.         item = 0;
  259.         MenuDefproc(mSizeMsg, m, r, gZeroPt, item);// recompute the menu size 
  260.     }
  261. }
  262.  
  263. //--------------------------------------------------------------------------------------------------
  264. #pragma segment MAMenuNever
  265.  
  266. pascal short TMenuView::FindItem(Point)
  267.  
  268. {
  269.     //SubClassResponsibility();
  270.     return 0;
  271. }
  272.  
  273. //--------------------------------------------------------------------------------------------------
  274. #pragma segment MAMenuRes
  275.  
  276. pascal void TMenuView::PostCommand(TCommand* command)// override 
  277. // ensure that trackers get tracked immediately 
  278.  
  279. {
  280.     if (command && command->IsMemberClass(GetClassIDFromName("TTracker")))
  281.     {
  282.         ++(gApplication->fEventLevel);
  283.         command->Process(); //!!! this->PerformCommand((TTracker*) command);
  284.         --(gApplication->fEventLevel);
  285.     }
  286.     else
  287.         inherited::PostCommand(command);
  288. }
  289.  
  290. //--------------------------------------------------------------------------------------------------
  291. #pragma segment MAMenuRes
  292.  
  293. pascal void TMenuView::HandleDefproc(short message,
  294.                                      MenuHandle theMenu,
  295.                                      Rect& menuRect,
  296.                                      Point hitPt,
  297.                                      short& whichItem)
  298.  
  299. {
  300.     GrafPtr savePort;
  301.     Rect r;
  302.     VRect VMenuRect;
  303.     VPoint VHitPt;
  304.  
  305.     // Save the wmgr port && set our private port 
  306.     GetPort(savePort);
  307.  
  308.     SetPort((GrafPtr) & pMenuCPort);
  309.     // Match the location and size that the menu mgr gives us 
  310.     MovePortTo(menuRect.left, menuRect.top);
  311.     PortSize(menuRect.Length(hSel), menuRect.Length(vSel));
  312.     fLocation.h = menuRect.left;
  313.     fLocation.v = menuRect.top;
  314.  
  315.     this->UpdateCoordinates();
  316.     if (this->Focus())
  317.     {
  318.         GlobalToLocal(hitPt);
  319.         GlobalToLocal(menuRect[topLeft]);
  320.         GlobalToLocal(menuRect[botRight]);
  321.  
  322.         this->SetEnable((((*fMenuHandle)->enableFlags) & 1) != 0);
  323.         switch (message)
  324.         {
  325.             case mDrawMsg:
  326. #if qDebugMsg
  327.                 if (gIntenseDebugging)
  328.                     fprintf(stderr, "mDrawMsg");
  329. #endif
  330.  
  331.                 this->HandleDrawMessage(message, theMenu, menuRect, hitPt, whichItem);
  332.                 break;
  333.                     
  334.             case mChooseMsg:
  335. #if qDebugMsg
  336.                 if (gIntenseDebugging)
  337.                     fprintf(stderr, "mChooseMsg");
  338. #endif
  339.  
  340.                 this->HandleChooseMessage(message, theMenu, menuRect, hitPt, whichItem);
  341.                 break;
  342.                     
  343.             case mSizeMsg:
  344. #if qDebugMsg
  345.                 if (gIntenseDebugging)
  346.                     fprintf(stderr, "mSizeMsg");
  347. #endif
  348.  
  349.                 this->HandleSizeMessage(message, theMenu, menuRect, hitPt, whichItem);
  350.                 break;
  351.                     
  352.             case mPopUpMsg:
  353. #if qDebugMsg
  354.                 if (gIntenseDebugging)
  355.                     fprintf(stderr, "mPopUpMsg");
  356. #endif
  357.  
  358.                 this->HandlePopUpMessage(message, theMenu, menuRect, hitPt, whichItem);
  359.                 break;
  360.  
  361. #if qDebugMsg
  362.             default:
  363.                 if (gIntenseDebugging)
  364.                     fprintf(stderr, "otherwise message");
  365.                 break;
  366. #endif
  367.  
  368.         }
  369.  
  370.         LocalToGlobal(menuRect[topLeft]);
  371.         LocalToGlobal(menuRect[botRight]);
  372.  
  373.         this->InvalidateFocus();
  374.     }
  375.  
  376.     SetPort(savePort);
  377. }
  378.  
  379. //--------------------------------------------------------------------------------------------------
  380. #pragma segment MAMenuRes
  381.  
  382. pascal void TMenuView::HandleChooseMessage(short,
  383.                                            MenuHandle,
  384.                                            Rect& ,
  385.                                            Point hitPt,
  386.                                            short& whichItem)
  387.  
  388. {
  389.     short newItem = kNoMenuItem;
  390.     Boolean saveTrackingInMenu = gTrackingInMenu;
  391.  
  392.     // so that trackers get a chance to know that they're tracking in menus 
  393.     gTrackingInMenu = TRUE;
  394.  
  395.     if (this->IsEnabled())                            // menu enabled 
  396.     {
  397.         Rect hitRect(0, 0, 0, 0);
  398.  
  399.         // see if point is within hit area 
  400.         this->GetQDExtent(hitRect);
  401.         hitRect[topLeft] += fBorder[topLeft];
  402.         hitRect[botRight] += fBorder[botRight];
  403.  
  404.         if (hitRect.Contains(hitPt))            // in menu (not border) 
  405.         {
  406.             TToolboxEvent * event = NULL;
  407.             EventRecord anEventRecord;
  408.  
  409.             // NOTE: Either your subclass of TTearOffMenu should override DoMouseCommand or one of
  410.             // TTearOffMenu's view's subview's should override DoMouseCommand so that it
  411.             // creates and posts a TTracker. TTearOffMenu's override of PostCommand will
  412.             // ensure that the tracker is tracked immediately. The tracker, having been
  413.             // posted and tracked, will then get executed next time PerformCommand is
  414.             // called. So, when we're done with HandleMouseDown below, we simply tell the
  415.             // menu manager that no menu item was selected, ie newItem == kNoMenuItem.
  416.  
  417.             this->CreateMouseDownEventInfo(hitPt, anEventRecord, event);
  418.             if (!HandleMouseDown(hitPt, event, gStdHysteresis))
  419.             {
  420.                 // NOTE: for backwards compatibility with MacApp 2.0 - override your TMenuView subclass'
  421.                 // HandleMouseDown method to return FALSE, and all should work as before
  422.  
  423.                 newItem = this->FindItem(hitPt);
  424.                 this->UpdateHighlight(whichItem, newItem);// Update highlighting 
  425.             }
  426.         }
  427.     }
  428.     else
  429.         this->UpdateHighlight(whichItem, newItem);    // Update highlighting 
  430.  
  431.     gTrackingInMenu = saveTrackingInMenu;
  432.  
  433.     // Tell MenuManager about new item 
  434.     whichItem = newItem;
  435. }
  436.  
  437. //--------------------------------------------------------------------------------------------------
  438. #pragma segment MAMenuRes
  439.  
  440. pascal void TMenuView::HandleDrawMessage(short,
  441.                                          MenuHandle,
  442.                                          Rect& ,
  443.                                          Point,
  444.                                          short&)
  445.  
  446. {
  447.     this->DrawContents();
  448.     fHighlighted = false;
  449.     if (!IsEnabled())
  450.     {
  451.         Rect extent(0, 0, 0, 0);
  452.         PenPat(qd.gray);
  453.         PenMode(notSrcBic);
  454.         this->GetQDExtent(extent);
  455.         PaintRect(extent);
  456.     }
  457. }
  458.  
  459. //--------------------------------------------------------------------------------------------------
  460. #pragma segment MAMenuRes
  461.  
  462. pascal void TMenuView::HandleSizeMessage(short,
  463.                                          MenuHandle,
  464.                                          Rect& ,
  465.                                          Point,
  466.                                          short&)
  467.  
  468. {
  469.     VPoint vp(0, 0);
  470.  
  471.     this->ComputeSize(vp);
  472.     (*fMenuHandle)->menuWidth = (short)vp.h;
  473.     (*fMenuHandle)->menuHeight = (short)vp.v;
  474. }
  475.  
  476. //--------------------------------------------------------------------------------------------------
  477. #pragma segment MAMenuRes
  478.  
  479. pascal void TMenuView::HandlePopUpMessage(short,
  480.                                           MenuHandle,
  481.                                           Rect& menuRect,
  482.                                           Point hitPt,
  483.                                           short&)
  484.  
  485. {
  486.     VPoint vp(0, 0);
  487.  
  488.     //  SubPt(origin, hitPt);
  489.  
  490.     menuRect.top = hitPt.h;
  491.     menuRect.left = hitPt.v;
  492.     this->ComputeSize(vp);
  493.     menuRect.bottom = (short)(menuRect.top + vp.v);
  494.     menuRect.right = (short)(menuRect.left + vp.h);
  495. }
  496.  
  497. //--------------------------------------------------------------------------------------------------
  498. #pragma segment MAMenuRes
  499.  
  500. pascal void TMenuView::Highlight(short,
  501.                                  Boolean)
  502.  
  503. {
  504.     this->SubClassResponsibility();
  505. }
  506.  
  507. //--------------------------------------------------------------------------------------------------
  508. #pragma segment MAFields
  509.  
  510. pascal void TMenuView::Fields(TObject* obj)        // override 
  511.  
  512. {
  513.     obj->DoToField("fFlashInterval", (Ptr) & fFlashInterval, bLongInt);
  514.     obj->DoToField("fNextFlash", (Ptr) & fNextFlash, bLongInt);
  515.     obj->DoToField("fHighlighted", (Ptr) & fHighlighted, bBoolean);
  516.     obj->DoToField("fMenuHandle", (Ptr) & fMenuHandle, bHandle);
  517.     obj->DoToField("fBorder", (Ptr) & fBorder, bRect);
  518.  
  519.     inherited::Fields(obj);
  520. }
  521.  
  522. //--------------------------------------------------------------------------------------------------
  523. #pragma segment MAMenuRes
  524. pascal Boolean TMenuView::IsItemEnabled(short item)
  525.  
  526. {
  527.     return (*fMenuHandle)->enableFlags & item;
  528. }
  529.  
  530. //--------------------------------------------------------------------------------------------------
  531. #pragma segment MAMenuRes
  532.  
  533. pascal void TMenuView::GetMenuViewColors(short theMenu,
  534.                                          short theItem,
  535.                                          MenuColors& theMenuColors)
  536.  
  537. {
  538.     typedef char TypeOfMenuInfo;
  539.     enum
  540.     {
  541.         aMenuItem = 0
  542.     };
  543.  
  544.  
  545.     enum
  546.     {
  547.         aMenuTitle = 1
  548.     };
  549.  
  550.  
  551.     enum
  552.     {
  553.         aMenuBar = 2
  554.     };
  555.  
  556.  
  557.     enum
  558.     {
  559.         noType = 3
  560.     };
  561.  
  562.  
  563.     MCEntryPtr aMCEntryPtr;
  564.     TypeOfMenuInfo typeOfRequest;
  565.     TypeOfMenuInfo typeOfEntryFound;
  566.     short theEntryMenu = theMenu;
  567.     short theEntryItem = theItem;
  568.  
  569.     if (qNeedsColorQD || gConfiguration.hasColorQD)
  570.     {
  571.         if (theItem != 0)
  572.             typeOfRequest = aMenuItem;
  573.         else if (theMenu != 0)
  574.             typeOfRequest = aMenuTitle;
  575.         else
  576.             typeOfRequest = aMenuBar;
  577.  
  578.         aMCEntryPtr = GetMCEntry(theEntryMenu, theEntryItem);
  579.         if (aMCEntryPtr == NULL)                // not found, try as title 
  580.         {
  581.             theEntryItem = 0;
  582.             aMCEntryPtr = GetMCEntry(theEntryMenu, theEntryItem);
  583.             if (aMCEntryPtr == NULL)            // not found, try as menubar 
  584.             {
  585.                 theEntryMenu = 0;
  586.                 aMCEntryPtr = GetMCEntry(theEntryMenu, theEntryItem);
  587.             }
  588.         }
  589.  
  590.         if (aMCEntryPtr == NULL)
  591.             typeOfEntryFound = noType;
  592.         else
  593.         {
  594.             if (theEntryItem != 0)
  595.                 typeOfEntryFound = aMenuItem;
  596.             else if (theEntryMenu != 0)
  597.                 typeOfEntryFound = aMenuTitle;
  598.             else
  599.                 typeOfEntryFound = aMenuBar;
  600.         }
  601.  
  602.         switch (typeOfEntryFound)
  603.         {
  604.             case aMenuItem:
  605.                 theMenuColors.itemColor = (*aMCEntryPtr).mctRGB1;
  606.                 theMenuColors.backgroundColor = (*aMCEntryPtr).mctRGB4;
  607.                 theMenuColors.markColor = (*aMCEntryPtr).mctRGB1;
  608.                 theMenuColors.commandColor = (*aMCEntryPtr).mctRGB1;
  609.                 break;
  610.                     
  611.             case aMenuTitle:
  612.                 switch (typeOfRequest)
  613.                 {
  614.                     case aMenuItem:
  615.                         {
  616.                             theMenuColors.itemColor = (*aMCEntryPtr).mctRGB3;
  617.                             theMenuColors.backgroundColor = (*aMCEntryPtr).mctRGB4;
  618.                             theMenuColors.markColor = (*aMCEntryPtr).mctRGB3;
  619.                             theMenuColors.commandColor = (*aMCEntryPtr).mctRGB3;
  620.                             break;
  621.                         }
  622.                     case aMenuTitle:
  623.                         {
  624.                             theMenuColors.itemColor = (*aMCEntryPtr).mctRGB1;
  625.                             theMenuColors.backgroundColor = (*aMCEntryPtr).mctRGB2;
  626.                             theMenuColors.markColor = (*aMCEntryPtr).mctRGB1;
  627.                             theMenuColors.commandColor = (*aMCEntryPtr).mctRGB1;
  628.                             break;
  629.                         }
  630.                 }
  631.                 break;
  632.                 
  633.             case aMenuBar:
  634.                 switch (typeOfRequest)
  635.                 {
  636.                     case aMenuItem:
  637.                         theMenuColors.itemColor = (*aMCEntryPtr).mctRGB3;
  638.                         theMenuColors.backgroundColor = (*aMCEntryPtr).mctRGB2;
  639.                         theMenuColors.markColor = (*aMCEntryPtr).mctRGB3;
  640.                         theMenuColors.commandColor = (*aMCEntryPtr).mctRGB3;
  641.                         break;
  642.                         
  643.                     case aMenuTitle:
  644.                         theMenuColors.itemColor = (*aMCEntryPtr).mctRGB1;
  645.                         theMenuColors.backgroundColor = (*aMCEntryPtr).mctRGB4;
  646.                         theMenuColors.markColor = (*aMCEntryPtr).mctRGB1;
  647.                         theMenuColors.commandColor = (*aMCEntryPtr).mctRGB1;
  648.                         break;
  649.                         
  650.                     case aMenuBar:
  651.                         theMenuColors.itemColor = (*aMCEntryPtr).mctRGB1;
  652.                         theMenuColors.backgroundColor = (*aMCEntryPtr).mctRGB4;
  653.                         theMenuColors.markColor = (*aMCEntryPtr).mctRGB1;
  654.                         theMenuColors.commandColor = (*aMCEntryPtr).mctRGB1;
  655.                         break;
  656.                 }
  657.                 break;
  658.                 
  659.             case noType:
  660.                 theMenuColors.itemColor = gRGBBlack;
  661.                 theMenuColors.backgroundColor = gRGBWhite;
  662.                 theMenuColors.markColor = gRGBBlack;
  663.                 theMenuColors.commandColor = gRGBBlack;
  664.                 break;
  665.         }
  666.     }
  667.     else
  668.     {
  669.         theMenuColors.itemColor = gRGBBlack;
  670.         theMenuColors.backgroundColor = gRGBWhite;
  671.         theMenuColors.markColor = gRGBBlack;
  672.         theMenuColors.commandColor = gRGBBlack;
  673.     }
  674. }
  675.  
  676. //--------------------------------------------------------------------------------------------------
  677. #pragma segment MAMenuRes
  678.  
  679. pascal void TMenuView::UpdateHighlight(short oldItem,
  680.                                        short newItem)
  681.  
  682. {
  683.     // Update highlighting 
  684.     if (newItem == oldItem)
  685.     {
  686.         if (fFlashInterval >= 0)
  687.             if (TickCount() > fNextFlash)
  688.             {
  689.                 fHighlighted =!fHighlighted;
  690.                 this->Highlight(oldItem, fHighlighted);
  691.                 fNextFlash = Future(fFlashInterval);
  692.             }
  693.     }
  694.     else
  695.     {
  696.         if (fHighlighted)
  697.             if (oldItem != kNoMenuItem)
  698.                 this->Highlight(oldItem, false);
  699.  
  700.         fHighlighted = (newItem != kNoMenuItem);
  701.         if (fHighlighted)
  702.             this->Highlight(newItem, TRUE);
  703.  
  704.         if (fFlashInterval >= 0)
  705.             fNextFlash = Future(fFlashInterval);
  706.     }
  707. }
  708.  
  709. //--------------------------------------------------------------------------------------------------
  710. #pragma segment MAMenuRes
  711.  
  712. pascal Boolean TMenuView::Focus(void)            // override 
  713.  
  714. {
  715.     Rect r;
  716.     VPoint vorigin;
  717.     MenuColors theMenuColors;
  718.  
  719.     if (inherited::Focus())
  720.     {
  721.         /* Try to make the best match for the menu colors without requiring programmer intervention.
  722.           by setting the color environment to be for items. */
  723.  
  724.         this->GetMenuViewColors((*fMenuHandle)->menuID, 1, theMenuColors);
  725.         SetIfColor(theMenuColors.itemColor);
  726.         SetIfBkColor(theMenuColors.backgroundColor);
  727.         return TRUE;
  728.     }
  729.     else
  730.         return FALSE;
  731. }
  732.  
  733. //--------------------------------------------------------------------------------------------------
  734. #pragma segment MAMenuRes
  735.  
  736. pascal void TMenuView::CreateMouseDownEventInfo(Point hitPt,
  737.                                                 EventRecord& anEventRecord,
  738.                                                 TToolboxEvent* event)
  739.  
  740. {
  741.     // !!! it would be nice to ask the application for these values from the last EventInfo 
  742.     anEventRecord.what = mouseDown;
  743.     anEventRecord.message = 0;
  744.     anEventRecord.when = TickCount();
  745.     anEventRecord.where = hitPt;
  746.     anEventRecord.modifiers = 0;
  747.  
  748.     event->fEventRecord = anEventRecord;
  749.     event->fBtnState = Button();
  750.     event->fCmdKey = IsCommandKeyDown();
  751.     event->fShiftKey = FALSE;
  752.     event->fAlphaLock = FALSE;
  753.     event->fOptionKey = IsOptionKeyDown();
  754.     event->fControlKey = FALSE;
  755.     event->fAutoKey = FALSE;
  756.     event->fCharacter = (char)0;
  757.     event->fKeyCode = 0;
  758.     event->fClickCount = gApplication->fClickCount;
  759.     event->fAffectsMenus = FALSE;
  760. }
  761.  
  762. //--------------------------------------------------------------------------------------------------
  763. #pragma segment MAMenuRes
  764.  
  765. pascal Boolean TMenuView::FocusOnSuperView(void)// override 
  766.  
  767. {
  768.     SetPort((GrafPtr) & pMenuCPort);
  769.     ClipRect(qd.thePort->portRect);
  770.     return TRUE;
  771. }
  772.  
  773. //--------------------------------------------------------------------------------------------------
  774. #pragma segment MAMenuRes
  775.  
  776. pascal GrafPtr TMenuView::GetGrafPort(void)        // override 
  777.  
  778. {
  779.     return (GrafPtr) & pMenuCPort;
  780. }
  781.  
  782.  
  783.